﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using DBSourceToolsLib;
using ITDM;
using StructureMap;

namespace DBSourceToolsCmd
{
    class Program
    {
        private static bool processFailed = false;

        static int Main(string[] args)
        {

            Console.WriteLine("DBSourceTools - Command line instance started.");
                
            ConsoleCmdLine ccl = new ConsoleCmdLine();
            CmdLineString projectName = new CmdLineString("project", true, "The .dbsp project file name.");
            CmdLineString sourceNickName = new CmdLineString("source-nick", true, "The source database nick name.");
            CmdLineString targetNickName = new CmdLineString("target-nick", true, "The target database nick name.");

            ccl.RegisterParameter(projectName);
            ccl.RegisterParameter(sourceNickName);
            ccl.RegisterParameter(targetNickName);

            ccl.Parse(args);

            
            Console.WriteLine("Project found   : " + projectName.Value);
            Console.WriteLine("Source database : " + sourceNickName);
            Console.WriteLine("Target database : " + targetNickName);

            ObjectFactory.Initialize(x => x.AddRegistry(new CommandLineRegistry()));
            UserSettings.Instance().StartupPath = Environment.CurrentDirectory;

            if (!File.Exists(projectName.Value) || !projectName.Value.EndsWith(".dbsp"))
            {
                Console.WriteLine("Please specify a valid .dbsp project file name for -project parameter.");
                return 1;
            }

            UserSettings.Instance().LoadLastProjectConfigFile(projectName.Value);

            ProcessCommandLineOptions(sourceNickName.Value, targetNickName.Value);

            if (processFailed)
            {
                Console.WriteLine("An error occurred. Exiting with code 1");
                return 1;
            }
            Console.WriteLine("Success");
            return 0;

        }

        private static void ProcessCommandLineOptions(string sourceNickName, string targetNickName)
        {
            SourceDatabase oSourceDb = UserSettings.Instance().getSourceDatabase(sourceNickName);
            oSourceDb.SysObjects.LoadFromDisk();
            oSourceDb.SysObjects.LoadDependencyTreeFromDisk();
            oSourceDb.ScriptOptions.LoadScriptOptionsFromDisk(null);


            if (oSourceDb == null)
                throw new ArgumentException("Could not find source database " + sourceNickName);

            TargetDatabase target = oSourceDb.TargetDatabases.SingleOrDefault(x => x.NickName == targetNickName);
            if (target == null)
                throw new ArgumentException("Could not find target database " + targetNickName + " that is a child of source database " + sourceNickName);

            Console.WriteLine("Starting : Write create script.");
            target.WriteCreateScript(UserSettings.Instance().DatabaseProject, null, false);
            Console.WriteLine("Ending   : Write create script.");

            Console.WriteLine("Starting : Deploy target.");
            DateHelper oHelper = new DateHelper();


            string strDate = String.Format("\\DeployResults_{0}_{1}.txt", oHelper.GetCurrentDateFormatted(),
                oHelper.GetCurrentTimeFormatted());

            string strOutputFileName = target.BaseDirectory + strDate;
            string executableFileName = target.BaseDirectory + "\\Run_Create_Scripts.bat";

            BatchRunner batchRunner = new BatchRunner(strOutputFileName, executableFileName, true);
            batchRunner.ProgressEventPublisher += new EventHandler<ProgressEventArgs>(BatchRunner_ProgressEventPublisher);
            batchRunner.RunUsingStreams();

            batchRunner.Join();

            Console.WriteLine("Ending   : Deploy target.");

        }

        static void BatchRunner_ProgressEventPublisher(object sender, ProgressEventArgs e)
        {
            Console.WriteLine(e.Message);
            if (e.IsError)
                processFailed = true;

        }
    }
}
